home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Multimedia / Resource Library: Multimedia.iso / maestro / source / timeline / pause.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-15  |  16.2 KB  |  469 lines

  1. /*
  2.  * Copyright (c) 1990, 1991 Stanford University
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software and 
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that (i) the above copyright notices and this permission notice appear in
  7.  * all copies of the software and related documentation, and (ii) the name
  8.  * Stanford may not be used in any advertising or publicity relating to
  9.  * the software without the specific, prior written permission of
  10.  * Stanford.
  11.  * 
  12.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  13.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  14.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  15.  *
  16.  * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
  17.  * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
  18.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT
  19.  * ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY,
  20.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21.  * SOFTWARE.
  22.  */
  23.  
  24. /* $Header: /Source/Media/collab/TimeLine/RCS/pause.c,v 1.0 91/09/30 17:02:22 chua Exp Locker: drapeau $ */
  25. /* $Log:    pause.c,v $
  26.  * Revision 1.0  91/09/30  17:02:22  chua
  27.  * Update to version 1.0
  28.  * 
  29.  * Revision 0.48  91/09/23  17:14:28  chua
  30.  * The Insert/Delete Pause Marker menu item is now found under the Options
  31.  * menu, instead of the Edit menu.
  32.  * 
  33.  * Revision 0.47  91/09/19  17:29:02  chua
  34.  * Make sure that variables are initialized properly.  Change formatting slightly,
  35.  * so that (if, for, while) statements with only one statement in them will not have
  36.  * braces.
  37.  * 
  38.  * Revision 0.46  91/08/05  16:53:28  chua
  39.  * Deleted the RepaintCanvas routine, as it is no longer necessary.  In places where it
  40.  * is called, just call the ScrollToFirstQuarter routine, which will do the necessary
  41.  * repaint as well.
  42.  * 
  43.  * Revision 0.45  91/08/05  13:05:15  chua
  44.  * Changed the name of the function call, ScrollToMiddle to ScrollToFirstQuarter.
  45.  * 
  46.  * Revision 0.44  91/07/30  17:32:56  chua
  47.  * When pause markers are inserted or deleted, set the change flag to 1.
  48.  * 
  49.  * Revision 0.43  91/07/26  17:27:35  chua
  50.  * In UpdatePauseList, include an extra parameter, refresh, to determine if a 
  51.  * canvas refresh is to be done after the updating.
  52.  * 
  53.  * Revision 0.42  91/07/24  10:55:10  chua
  54.  * Split the InsertPause procedure into two, with InsertNewPause being the other.
  55.  * InsertNewPause is called with a pointer to a new pause node as its parameter.
  56.  * The reason the split is done is so that this function can be called by the OpenHandler
  57.  * as well.
  58.  * There is also a FreePause procedure to free all nodes in a pause list.
  59.  * 
  60.  * Revision 0.41  91/07/22  15:22:22  chua
  61.  * 
  62.  * 
  63.  * Revision 0.40  91/07/22  15:03:12  chua
  64.  * This file contains the routines that deals with inserting and deleting pause markers from the
  65.  * TimeLine document.  The routines are:
  66.  * 
  67.  * InsertPauseMarkerHandler - opens the Pause popup window.
  68.  * FindPause - returns a pointer to a pause node, given its position in the pause list.
  69.  * PauseListNotify - notify procedure for the pause panel list.
  70.  * UpdatePauseList - function which will update the panel list from information in the pause linked list.
  71.  * InsertPause - inserts a new pause marker.
  72.  * DeletePause - deletes a selected pause marker.
  73.  * ClosePausePopup - closes the Pause popup window.
  74.  * ClearAllPause - clears all the pause markers.
  75.  *  */
  76.  
  77. static char gridrcsid[] = "$Header: /Source/Media/collab/TimeLine/RCS/pause.c,v 1.0 91/09/30 17:02:22 chua Exp Locker: drapeau $";
  78.  
  79. #include "main.h"
  80.  
  81. /*
  82.  * Menu handler for `OptionsMenu (Insert/Delete Pause Marker)'.
  83.  * This function will open the Pause popup window.
  84.  */
  85. Menu_item InsertPauseMarkerHandler(item, op)
  86.      Menu_item    item;
  87.      Menu_generate    op;
  88. {
  89.   TimeLineFramePtr tlFrame;
  90.   TimeLine_window_objects * ip = (TimeLine_window_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
  91.  
  92.   tlFrame = TimeLineWindow[xv_get(ip->controls, PANEL_CLIENT_DATA)];
  93.   switch (op) 
  94.   {
  95.    case MENU_DISPLAY:
  96.     break;
  97.    case MENU_DISPLAY_DONE:
  98.     break;
  99.    case MENU_NOTIFY:
  100.     xv_set(tlFrame->PausePopup->PausePopup,
  101.        FRAME_CMD_PUSHPIN_IN, TRUE, NULL);
  102.     xv_set(tlFrame->PausePopup->PausePopup,
  103.        XV_SHOW, TRUE, NULL);
  104.     break;
  105.    case MENU_NOTIFY_DONE:
  106.     break;
  107.   }
  108.   return item;
  109. }
  110.  
  111. /*
  112.  * Function that will return a pointer to the appropriate pause node given its relative position in the pause list.
  113.  */
  114. Pause *FindPause(tlFrame)
  115.      TimeLineFramePtr tlFrame;
  116. {
  117.   int         i;
  118.   Pause *currentPause;
  119.   
  120.   currentPause = tlFrame->pauseHead;                       
  121.   for (i=0; i < tlFrame->pauseEdit && currentPause != NULL; i++)
  122.     currentPause = currentPause->next;
  123.   return currentPause;
  124. }
  125.  
  126. /*
  127.  * Notify callback function for `PauseList'.
  128.  * On a PANEL_LIST_OP_DESELECT operation, this function will reset the selected pause message to zero, and also the pauseEdit and selectedPause
  129.  * variables to indicate that no edit has been selected.
  130.  * On a PANEL_LIST_OP_SELECT operation, this function will set the pauseEdit and selectedPause variables to point to the selected node and scroll
  131.  * the canvas so that the pause marker will be visible.
  132.  */
  133. int PauseListNotify(item, string, client_data, op, event)
  134.      Panel_item    item;
  135.      char        *string;
  136.      Xv_opaque    client_data;
  137.      Panel_list_op    op;
  138.      Event        *event;
  139. {
  140.   int selection;
  141.   char selected[4];
  142.   TimeLineFramePtr tlFrame;
  143.   Pause_PausePopup_objects    *ip = (Pause_PausePopup_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
  144.   Window    owner = xv_get(ip->PausePopup, XV_OWNER);
  145.   TimeLine_window_objects * tlip = (TimeLine_window_objects *) xv_get(owner, XV_KEY_DATA, INSTANCE);
  146.   
  147.   tlFrame = TimeLineWindow[xv_get(tlip->controls, PANEL_CLIENT_DATA)];
  148.   switch(op) 
  149.   {
  150.    case PANEL_LIST_OP_DESELECT:
  151.     tlFrame->pauseEdit = -1;
  152.     tlFrame->selectedPause = NULL;
  153.     sprintf(selected, "%d", tlFrame->pauseEdit + 1);
  154.     xv_set(tlFrame->PausePopup->PauseSelectValueMsg, PANEL_LABEL_STRING, selected, NULL);
  155.     break;
  156.    case PANEL_LIST_OP_SELECT:
  157.     sscanf(string, "%d", &selection);                    /* Get the number of the edit which has been selected */
  158.     tlFrame->pauseEdit = selection - 1;
  159.     tlFrame->selectedPause = (Pause *) FindPause(tlFrame);
  160.     ScrollToFirstQuarter(tlFrame, tlFrame->selectedPause->position, 0);
  161.     sprintf(selected, "%d", tlFrame->pauseEdit + 1);
  162.     xv_set(tlFrame->PausePopup->PauseSelectValueMsg, PANEL_LABEL_STRING, selected, NULL);
  163.     break;
  164.    case PANEL_LIST_OP_VALIDATE:
  165.     break;
  166.    case PANEL_LIST_OP_DELETE:
  167.     break;
  168.   }
  169.   return XV_OK;
  170. }
  171.  
  172. /*
  173.  * This function will update the pause panel list which indicates where all the pause markers are.
  174.  * It goes through the pause list for the frame and updates the panel list accordingly.
  175.  * The parameter, refresh, indicates if we need to do a canvas redraw.   This is usually necessary unless this function is called from
  176.  * the OpenHandler, in which case the refresh is done at the end of the loading of file.
  177.  */
  178. void UpdatePauseList(tlFrame, refresh)
  179.      TimeLineFramePtr tlFrame;
  180.      int refresh;
  181. {
  182.   Pause *currentPause;
  183.   char     buf[100], numpauses[5], selected[4];
  184.   int     count = 0, i;
  185.   int     oldlines, replace;
  186.   
  187.   sprintf(numpauses, "%d", tlFrame->numPause);                /* Update the display for the number of pauses */
  188.   xv_set(tlFrame->PausePopup->PauseCountMsg,
  189.      PANEL_LABEL_STRING, numpauses, NULL);
  190.   oldlines = xv_get(tlFrame->PausePopup->PauseList,            /* Get the number of rows currently in the panel list */
  191.             PANEL_LIST_NROWS);
  192.   replace = oldlines;
  193.   if (tlFrame->numPause <= oldlines) 
  194.     replace = tlFrame->numPause;
  195.   currentPause = tlFrame->pauseHead;
  196.   xv_set(tlFrame->PausePopup->PauseList,                /* Hide the panel list while updating is done */
  197.      XV_SHOW, FALSE, NULL);
  198.   for (i=0; i < replace; i++)                        /* Replace the old strings by the new ones. */
  199.   {
  200.     sprintf(buf, " %4d.          %4d:%02d",
  201.         count+1, currentPause->min, currentPause->sec); 
  202.     xv_set (tlFrame->PausePopup->PauseList,
  203.         PANEL_LIST_STRING, i, buf,
  204.         PANEL_LIST_FONT, i, font,
  205.         NULL);
  206.     count++;
  207.     currentPause = currentPause->next;
  208.   }
  209.   if (tlFrame->numPause > oldlines) 
  210.   {
  211.     for (i=oldlines; i < tlFrame->numPause; i++)            /* Insert the additional new strings */
  212.     {
  213.       sprintf(buf, " %4d.          %4d:%02d",
  214.           count+1, currentPause->min, currentPause->sec); 
  215.       xv_set (tlFrame->PausePopup->PauseList,
  216.           PANEL_LIST_INSERT, i,
  217.           PANEL_LIST_STRING, i, buf,
  218.           PANEL_LIST_FONT, i, font,
  219.           NULL);
  220.       count++;
  221.       currentPause = currentPause->next;
  222.     }
  223.   }
  224.   else                                /* Delete the excess old strings */
  225.   {
  226.     for (i=tlFrame->numPause; i < oldlines; i++)
  227.       xv_set(tlFrame->PausePopup->PauseList,
  228.          PANEL_LIST_DELETE, tlFrame->numPause,
  229.          NULL);
  230.   }
  231.   if (tlFrame->pauseEdit >= 0) 
  232.     xv_set(tlFrame->PausePopup->PauseList,                /* Select the newly added entry on the panel list */
  233.        PANEL_LIST_SELECT, tlFrame->pauseEdit, 
  234.        TRUE, NULL);
  235.   sprintf(selected, "%d", tlFrame->pauseEdit + 1);            /* Update the selected pause field */
  236.   xv_set(tlFrame->PausePopup->PauseSelectValueMsg, PANEL_LABEL_STRING, selected, NULL);
  237.   xv_set(tlFrame->PausePopup->PauseList,
  238.      XV_SHOW, TRUE, NULL);
  239.   if (refresh == 1) 
  240.     DrawCanvasRepaintHandler(tlFrame->TimeLine_window->DrawCanvas, tlFrame->paintWinDraw, 
  241.                  tlFrame->dpyDraw, tlFrame->xidDraw, NULL);
  242. }
  243.  
  244. /*
  245.  * This procedure will insert a new pause node in the pause list.  If the insert is successful, it will return the position of the new node in the
  246.  * list.  If not, it will return -1.
  247.  */
  248. int InsertNewPause(tlFrame, newPause)
  249.      TimeLineFramePtr tlFrame;
  250.      Pause *newPause;
  251. {
  252.   int selected;
  253.   int found;
  254.   Pause *currentPause;
  255.   
  256.   selected = 0;
  257.   if (tlFrame->pauseHead == NULL)                    /* Pause list is empty.  Insert at the beginning. */
  258.     tlFrame->pauseHead = newPause;
  259.   else                                    /* Go down the note list to find the appropriate position to insert */
  260.   {
  261.     currentPause = tlFrame->pauseHead;
  262.     if (currentPause->position == newPause->position)            /* We do not want to insert two pause markers at the same place */
  263.     {
  264.       free (newPause);
  265.       return -1;
  266.     }
  267.     found = 0;
  268.     if (currentPause->position > newPause->position) 
  269.     {
  270.       found = 1;
  271.       newPause->next = currentPause;
  272.       tlFrame->pauseHead = newPause;
  273.     }
  274.     else while (currentPause->next != NULL && !found)
  275.     {
  276.       selected ++;
  277.       if (currentPause->next->position == newPause->position)        /* We do not want to insert two pause markers at the same place */
  278.       {
  279.     free (newPause);
  280.     return -1;
  281.       }
  282.       if (currentPause->next->position < newPause->position) 
  283.     currentPause = currentPause->next;
  284.       else 
  285.       {
  286.     newPause->next = currentPause->next;
  287.     currentPause->next = newPause;
  288.     found = 1;
  289.       }
  290.     }
  291.     if (!found)                                /* Insert at the end of list */
  292.     {
  293.       selected ++;
  294.       currentPause->next = newPause;
  295.     }
  296.   }
  297.   return selected;
  298. }
  299.  
  300. /*
  301.  * Notify callback function for `InsertPauseButton'.
  302.  * Inserts a new pause marker at either the insertion point or specified time, depending on which checkbox the user has chosen.
  303.  * A new pause marker would not be inserted in the pause marker list if it starts at zero, or there is another pause marker that is already in the list
  304.  * having the same time.
  305.  */
  306. void InsertPause(item, event)
  307.      Panel_item    item;
  308.      Event        *event;
  309. {
  310.   Pause *newPause;
  311.   int selected;
  312.   TimeLineFramePtr tlFrame;
  313.   Pause_PausePopup_objects    *ip = (Pause_PausePopup_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
  314.   Window    owner = xv_get(ip->PausePopup, XV_OWNER);
  315.   TimeLine_window_objects * tlip = (TimeLine_window_objects *) xv_get(owner, XV_KEY_DATA, INSTANCE);
  316.  
  317.   tlFrame = TimeLineWindow[xv_get(tlip->controls, PANEL_CLIENT_DATA)];
  318.   newPause = (Pause *) malloc (sizeof(struct Pause));
  319.   newPause->next = NULL;
  320.   if (xv_get(ip->PauseChoice, PANEL_VALUE) == 0)            /* Insert at insertion point */
  321.   {
  322.     if (tlFrame->lastX < 0)                        /* If insertion point is not on the canvas, return */
  323.     {
  324.       free (newPause);
  325.       return;
  326.     }
  327.     newPause->position = tlFrame->lastX;
  328.     newPause->min = atoi(xv_get(ip->IPMinText, PANEL_VALUE));
  329.     newPause->sec = atoi((int) xv_get(ip->IPSecText, PANEL_VALUE));
  330.   }
  331.   else                                    /* Insert at the specified time */
  332.   {
  333.     newPause->sec = xv_get(ip->SPSecText, PANEL_VALUE);
  334.     newPause->min = xv_get(ip->SPMinText, PANEL_VALUE);
  335.     while (newPause->sec >= 60) 
  336.     {
  337.       newPause->min ++;
  338.       newPause->sec -= 60;
  339.     }
  340.     newPause->position = newPause->min * 60 * PixelsPerSecond +        /* Calculate the position in terms of pixels */
  341.       newPause->sec * PixelsPerSecond;
  342.   }
  343.   if (newPause->position == 0)                        /* No point in inserting a pause marker at zero time */
  344.   {
  345.     free (newPause);
  346.     return;
  347.   }
  348.   if ((selected = InsertNewPause(tlFrame, newPause)) == -1) 
  349.   {
  350.     free (newPause);
  351.     return;
  352.   }
  353.   tlFrame->numPause++;
  354.   tlFrame->pauseEdit = selected;
  355.   tlFrame->selectedPause = newPause;
  356.   ScrollToFirstQuarter(tlFrame, newPause->position, 1);            /* Scroll to make the newly inserted pause marker visible */
  357.   UpdatePauseList(tlFrame, 1);
  358.   tlFrame->change = 1;                            /* Set the change flag to 1 */
  359.   UpdateHeader(tlFrame, 1);
  360. }
  361.  
  362. /*
  363.  * Notify callback function for `DeletePauseButton'.
  364.  * Deletes a pause marker (only if one has been selected from the panel list).
  365.  */
  366. void DeletePause(item, event)
  367.      Panel_item    item;
  368.      Event        *event;
  369. {
  370.   TimeLineFramePtr tlFrame;
  371.   Pause *currentPause, *prevPause;
  372.   Pause_PausePopup_objects    *ip = (Pause_PausePopup_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
  373.   int found;
  374.   Window    owner = xv_get(ip->PausePopup, XV_OWNER);
  375.   TimeLine_window_objects * tlip = (TimeLine_window_objects *) xv_get(owner, XV_KEY_DATA, INSTANCE);
  376.   
  377.   tlFrame = TimeLineWindow[xv_get(tlip->controls, PANEL_CLIENT_DATA)];
  378.   if (tlFrame->pauseHead == NULL || tlFrame->pauseEdit == -1)        /* Pause list is empty, or there is no edit chosen */
  379.     return;    
  380.   xv_set(tlFrame->PausePopup->PauseList,                /* Deselect the selected entry on the panel list */
  381.      PANEL_LIST_SELECT, tlFrame->pauseEdit, 
  382.      FALSE, NULL);
  383.   currentPause = tlFrame->pauseHead;
  384.   if (currentPause == tlFrame->selectedPause) 
  385.     tlFrame->pauseHead = currentPause->next;
  386.   else 
  387.   {
  388.     prevPause = currentPause;
  389.     currentPause = currentPause->next;
  390.     found = 0;
  391.     while (currentPause != NULL && !found) 
  392.     {
  393.       if (currentPause == tlFrame->selectedPause) 
  394.       {
  395.     prevPause->next = currentPause->next;
  396.     found = 1;
  397.       }
  398.       prevPause = currentPause;
  399.       if (!found) 
  400.     currentPause = currentPause->next;
  401.     }
  402.   }
  403.   tlFrame->numPause --;
  404.   tlFrame->pauseEdit = -1;
  405.   tlFrame->selectedPause = NULL;
  406.   free (currentPause);
  407.   UpdatePauseList(tlFrame, 1);
  408.   tlFrame->change = 1;                            /* Set the change flag to 1 */
  409.   UpdateHeader(tlFrame, 1);
  410. }
  411.  
  412. /*
  413.  * Notify callback function for `PauseDoneProc'.
  414.  * Closes the pause popup window.
  415.  */
  416. void ClosePausePopup(item, event)
  417.      Panel_item    item;
  418.      Event        *event;
  419. {
  420.   Pause_PausePopup_objects    *ip = (Pause_PausePopup_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
  421.  
  422.   xv_set(ip->PausePopup, FRAME_CMD_PUSHPIN_IN, FALSE, NULL);
  423.   xv_set(ip->PausePopup, XV_SHOW, FALSE, NULL);
  424. }
  425.  
  426. /*
  427.  * Notify callback function for `ClearAllPauseButton'.
  428.  * This function will clear all the pause markers.  
  429.  */
  430. void ClearAllPause(item, event)
  431.      Panel_item    item;
  432.      Event        *event;
  433. {
  434.   TimeLineFramePtr tlFrame;
  435.   Pause_PausePopup_objects    *ip = (Pause_PausePopup_objects *) xv_get(item, XV_KEY_DATA, INSTANCE);
  436.   Window    owner = xv_get(ip->PausePopup, XV_OWNER);
  437.   TimeLine_window_objects * tlip = (TimeLine_window_objects *) xv_get(owner, XV_KEY_DATA, INSTANCE);
  438.   
  439.   tlFrame = TimeLineWindow[xv_get(tlip->controls, PANEL_CLIENT_DATA)];
  440.   if (tlFrame->numPause > 0) 
  441.   {
  442.     FreePause(tlFrame);
  443.     UpdatePauseList(tlFrame, 1);
  444.     tlFrame->change = 1;                        /* Set the change flag to 1 */
  445.     UpdateHeader(tlFrame, 1);
  446.   }
  447. }
  448.  
  449. /*
  450.  * This procedure will free all the pause nodes in a pause list.
  451.  */
  452. void FreePause(tlFrame)
  453.      TimeLineFramePtr tlFrame;
  454. {
  455.   Pause *pause, *freePause;
  456.   
  457.   pause = tlFrame->pauseHead;                        /* Free all the pause nodes */
  458.   while (pause != NULL) 
  459.   {
  460.     freePause = pause;
  461.     pause = pause->next;
  462.     free (freePause);
  463.   }
  464.   tlFrame->pauseHead = NULL;
  465.   tlFrame->pauseEdit = -1;
  466.   tlFrame->selectedPause = NULL;
  467.   tlFrame->numPause = 0;
  468. }
  469.